const textColor = '#424E61'
const fontSize = '12px'

// 后续适配大屏使用
export let chartFontSize = 1
window.addEventListener('resize', updateChartFontSize)
function updateChartFontSize () {
  const clientWidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
  if (!clientWidth) {
    chartFontSize = 1
    return
  }
  chartFontSize = clientWidth / 1080
}
export function chartFontSizeFunc (res) {
  return res * chartFontSize
}
const emphasis = {
  scale: false,
  itemStyle: {
    color: 'inherit'
  }
}

// 蓝 绿 黄 橙 红
export const legendColors = ['#0090FF', '#00E5C0', '#FFD96D', '#FF9C57', '#FF5757']

// 环状图
export function getRingOption ({
  // 颜色
  color,
  // 数据 [{name: '名称', value: 1 }]
  data
}) {
  const seriesData = []
  // 消除数值过小导致间隔太大的问题
  let sum = 0
  for (const item of data) {
    sum += item.value
  }
  const factor = 100 / sum
  for (let i = 0; i < data.length; i++) {
    seriesData.push({
      value: data[i].value * factor,
      name: data[i].name,
      itemStyle: {
        borderWidth: 5,
        shadowBlur: 10,
        borderColor: color[i],
        shadowColor: color[i],
        borderRadius: '50%'
      }
    })
    seriesData.push({
      value: 5,
      name: '',
      itemStyle: {
        label: {
          show: false
        },
        labelLine: {
          show: false
        },
        color: 'rgba(0, 0, 0, 0)',
        borderColor: 'rgba(0, 0, 0, 0)',
        borderWidth: 0
      }
    })
  }
  return {
    color: color,
    title: {
      show: false
    },
    tooltip: {
      show: false
    },
    legend: {
      show: false
    },
    series: [
      {
        type: 'pie',
        zlevel: 1,
        silent: true,
        radius: ['98%', '97%'],
        hoverAnimation: false,
        animation: false,
        label: {
          show: false
        },
        labelLine: {
          show: false
        },
        data: [
          { name: '', value: 30, itemStyle: { color: getGradientColor('#16589888', '#ffffff00') } },
          { name: '', value: 40, itemStyle: { color: 'rgb(0,0,0,0)' } },
          { name: '', value: 30, itemStyle: { color: getGradientColor('#16589888', '#ffffff00') } }
        ]
      },
      {
        type: 'pie',
        zlevel: 1,
        silent: true,
        radius: ['93%', '92%'],
        hoverAnimation: false,
        animation: false,
        label: {
          show: false
        },
        labelLine: {
          show: false
        },
        data: [
          { name: '', value: 40, itemStyle: { color: getGradientColor('#2386d9', '#ffffff00') } },
          { name: '', value: 20, itemStyle: { color: 'rgb(0,0,0,0)' } },
          { name: '', value: 40, itemStyle: { color: getGradientColor('#2386d9', '#ffffff00') } }
        ]
      },
      {
        name: '',
        type: 'pie',
        emphasis,
        radius: ['80%', '84%'],
        center: ['50%', '50%'],
        label: {
          show: false
        },
        data: seriesData
      }
    ]
  }
}

// 极坐标 + roseType
export function getRoseOption ({
  color,
  data
}) {
  return {
    color,
    polar: {},
    angleAxis: {
      interval: 1,
      type: 'category',
      data: [],
      z: 10,
      axisLine: {
        show: false
      },
      axisLabel: {
        show: false
      }
    },
    radiusAxis: {
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        show: false
      },
      min: 20,
      max: 100,
      interval: 20,
      splitLine: {
        lineStyle: {
          color: '#CCE9FF',
          width: 2,
          type: 'solid'
        }
      }
    },
    series: [{
      type: 'pie',
      radius: ['5%', '10%'],
      label: {
        show: false
      },
      emphasis,
      data: [{
        name: '',
        value: 0,
        itemStyle: {
          color: '#CCE9FF'
        }
      }]
    }, {
      type: 'pie',
      radius: ['90%', '95%'],
      name: '',
      label: {
        show: false
      },
      emphasis,
      data: [{
        name: '',
        value: 0,
        itemStyle: {
          color: '#CCE9FF'
        }
      }]
    }, {
      stack: 'a',
      type: 'pie',
      radius: ['20%', '80%'],
      roseType: 'area',
      zlevel: 10,
      emphasis,
      label: {
        show: false
      },
      data
    }]
  }
}

export const maxBarWidth = 14

// 折线图 柱状图
export function getBarOption ({
  // y轴名称
  yAxisName = '',
  // 需要根据y轴名称动态调整
  yAxisNameLeftPadding = -10,
  // 是否面积图
  isArea = false,
  // 是否堆叠图
  isStack = false,
  // 是否显示图例
  hasLegend = false,
  // 是否旋转轴标签
  textRotate = false,
  // 是否翻转x轴和y轴
  reverse = false,
  // 类目轴数据
  xAxis = [],
  series = []
}) {
  const _series = []
  let index = 0
  for (const s of series) {
    if (s.type === 'line') {
      // 折线图
      _series.push({
        ...s,
        itemStyle: {
          color: s.color
        },
        areaStyle: isArea ? {
          color: s.color ? getGradientColor(s.color, '#ffffff00') : null
        } : null
      })
    } else {
      _series.push({
        ...s,
        type: 'bar',
        stack: isStack ? 'all' : '',
        barMaxWidth: maxBarWidth,
        itemStyle: {
          // borderRadius: isStack ? null : (reverse ? [0, maxBarWidth, maxBarWidth, 0] : [maxBarWidth, maxBarWidth, 0, 0]),
          color: s.color ? Array.isArray(s.color) ? getGradientColor(s.color[1], s.color[0]) : s.color : null
        },
        z: series.length - index
      })
    }
    index++
  }
  const _xAxis = {
    type: 'category',
    data: xAxis,
    axisLine: {
      show: false
    },
    axisTick: {
      show: false
    },
    axisLabel: {
      color: textColor,
      fontSize,
      rotate: textRotate ? 45 : 0,
      formatter: function (name) {
        return (name.length > 8 ? (name.slice(0, 10) + '...') : name)
      }
    }
  }
  const _yAxis = {
    name: yAxisName,
    nameTextStyle: {
      color: textColor,
      padding: [0, 0, 0, yAxisNameLeftPadding]
    },
    type: 'value',
    minInterval: 1,
    axisLine: {
      show: false
    },
    axisTick: {
      show: false
    },
    axisLabel: {
      color: textColor,
      fontSize
    },
    splitLine: {
      lineStyle: {
        type: 'solid',
        color: '#E6E9EF'
      }
    }
  }
  const option = {
    legend: {
      show: hasLegend,
      top: 8,
      data: hasLegend ? _series.map(s => s.name) : [],
      textStyle: {
        color: '#747C8B'
      },
      itemWidth: 10,
      itemHeight: 10,
      formatter: function (name) {
        return (name.length > 8 ? (name.slice(0, 8) + '...') : name)
      }
    },
    tooltip: {
      trigger: 'axis'
    },
    grid: {
      top: hasLegend ? 50 : 40,
      left: 10,
      right: reverse ? 60 : 10,
      bottom: 20,
      containLabel: true
    },
    xAxis: reverse ? _yAxis : _xAxis,
    yAxis: reverse ? _xAxis : _yAxis,
    series: _series
  }
  return option
}

// 生成模拟 3D 饼图的配置项
export function getPie3D (pieData, internalDiameterRatio) {
  const series = []
  let sumValue = 0
  let startValue = 0
  let endValue = 0
  const legendData = []
  const k = typeof internalDiameterRatio !== 'undefined' ? (1 - internalDiameterRatio) / (1 + internalDiameterRatio) : 1 / 3

  // 为每一个饼图数据，生成一个 series-surface 配置
  for (let i = 0; i < pieData.length; i++) {
    sumValue += pieData[i].value
    const seriesItem = {
      name: typeof pieData[i].name === 'undefined' ? `series${i}` : pieData[i].name,
      type: 'surface',
      parametric: true,
      wireframe: {
        show: false
      },
      pieData: pieData[i],
      pieStatus: {
        selected: false,
        hovered: false,
        k: k
      }
    }
    seriesItem.itemStyle = {
      opacity: 0.8,
      color: pieData[i].color
    }
    series.push(seriesItem)
  }
  // 使用上一次遍历时，计算出的数据和 sumValue，调用 getParametricEquation 函数，
  // 向每个 series-surface 传入不同的参数方程 series-surface.parametricEquation，也就是实现每一个扇形。
  for (let i = 0; i < series.length; i++) {
    endValue = startValue + series[i].pieData.value
    series[i].pieData.startRatio = startValue / sumValue
    series[i].pieData.endRatio = endValue / sumValue
    series[i].parametricEquation = getParametricEquation(series[i].pieData.startRatio, series[i].pieData.endRatio, false, false, k, series[i].pieData.value)

    startValue = endValue

    legendData.push(series[i].name)
  }

  // 准备待返回的配置项，把准备好的 legendData、series 传入。
  const option = {
    tooltip: {
      formatter: params => {
        if (params.seriesName !== 'mouseoutSeries') {
          const pieData = option.series[params.seriesIndex].pieData
          return `${params.seriesName}<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${params.color};"></span>${pieData.raw} 占比 ${pieData.percentage}%`
        }
      }
    },
    backgroundColor: 'transparent',
    xAxis3D: {
      min: -1,
      max: 1
    },
    yAxis3D: {
      min: -1,
      max: 1
    },
    zAxis3D: {
      min: -1,
      max: 1
    },
    grid3D: {
      show: false,
      boxHeight: 20,
      bottom: '50%',
      // environment: '#021041',
      viewControl: {
        distance: 180,
        alpha: 25,
        beta: 30
      }

    },
    series: series
  }
  return option
}

export function getGradientColor (startColor, endColor) {
  return {
    type: 'linear',
    x: 0,
    y: 0,
    x2: 0,
    y2: 1,
    colorStops: [
      { offset: 0, color: startColor },
      { offset: 1, color: endColor }
    ]
  }
}

/*************************
*************************
【 getParametricEquation 函数说明 】 :
*************************
    根据传入的
    startRatio（浮点数）: 当前扇形起始比例，取值区间 [0, endRatio)
    endRatio（浮点数）: 当前扇形结束比例，取值区间 (startRatio, 1]
    isSelected（布尔值）:是否选中，效果参照二维饼图选中效果（单选）
    isHovered（布尔值）: 是否放大，效果接近二维饼图高亮（放大）效果（未能实现阴影）
    k（0~1之间的浮点数）：用于参数方程的一个参数，取值 0~1 之间，通过「内径/外径」的值换算而来。

    生成 3D 扇形环曲面

*************************
【 getPie3D 函数说明 】 :
*************************
    根据传入的
    pieData（object）：饼图数据
    internalDiameterRatio（0~1之间的浮点数）：内径/外径的值（默认值 1/2），当该值等于 0 时，为普通饼图

    生成模拟 3D 饼图的配置项 option

    备注：饼图数据格式示意如下
    [{
        name: '数据1',
        value: 10
    }, {
        // 数据项名称
        name: '数据2',
        value : 56,
        itemStyle:{
            // 透明度
            opacity: 0.5,
            // 扇形颜色
            color: 'green'
        }
    }]

*************************
【 鼠标事件监听说明 】 :
*************************
    click： 实现饼图的选中效果（单选）
            大致思路是，通过监听点击事件，获取到被点击数据的系列序号 params.seriesIndex，
            然后将对应扇形向外/向内移动 10% 的距离。

    mouseover： 近似实现饼图的高亮（放大）效果
            大致思路是，在饼图外部套一层透明的圆环，然后监听 mouseover 事件，获取
            到对应数据的系列序号 params.seriesIndex 或系列名称 params.seriesName，
            如果鼠标移到了扇形上，则先取消高亮之前的扇形（如果有）,再高亮当前扇形；
            如果鼠标移到了透明圆环上，则只取消高亮之前的扇形（如果有），不做任何高亮。

    globalout： 当鼠标移动过快，直接划出图表区域时，有可能监听不到透明圆环的 mouseover，
            导致此前高亮没能取消，所以补充了对 globalout 的监听。

*************************/

// 生成扇形的曲面参数方程，用于 series-surface.parametricEquation
function getParametricEquation (startRatio, endRatio, isSelected, isHovered, k, height) {
  // 计算
  const midRatio = (startRatio + endRatio) / 2
  const startRadian = startRatio * Math.PI * 2
  const endRadian = endRatio * Math.PI * 2
  const midRadian = midRatio * Math.PI * 2
  // 如果只有一个扇形，则不实现选中效果。
  if (startRatio === 0 && endRatio === 1) {
    isSelected = false
  }
  // 通过扇形内径/外径的值，换算出辅助参数 k（默认值 1/3）
  k = typeof k !== 'undefined' ? k : 1 / 3
  // 计算选中效果分别在 x 轴、y 轴方向上的位移（未选中，则位移均为 0）
  const offsetX = isSelected ? Math.cos(midRadian) * 0.1 : 0
  const offsetY = isSelected ? Math.sin(midRadian) * 0.1 : 0
  // 计算高亮效果的放大比例（未高亮，则比例为 1）
  const hoverRate = isHovered ? 1.05 : 1
  // 返回曲面参数方程
  return {
    u: {
      min: -Math.PI,
      max: Math.PI * 3,
      step: Math.PI / 32
    },
    v: {
      min: 0,
      max: Math.PI * 2,
      step: Math.PI / 20
    },
    x: function (u, v) {
      if (u < startRadian) {
        return offsetX + Math.cos(startRadian) * (1 + Math.cos(v) * k) * hoverRate
      }
      if (u > endRadian) {
        return offsetX + Math.cos(endRadian) * (1 + Math.cos(v) * k) * hoverRate
      }
      return offsetX + Math.cos(u) * (1 + Math.cos(v) * k) * hoverRate
    },
    y: function (u, v) {
      if (u < startRadian) {
        return offsetY + Math.sin(startRadian) * (1 + Math.cos(v) * k) * hoverRate
      }
      if (u > endRadian) {
        return offsetY + Math.sin(endRadian) * (1 + Math.cos(v) * k) * hoverRate
      }
      return offsetY + Math.sin(u) * (1 + Math.cos(v) * k) * hoverRate
    },
    z: function (u, v) {
      if (u < -Math.PI * 0.5) {
        return Math.sin(u)
      }
      if (u > Math.PI * 2.5) {
        return Math.sin(u)
      }
      return Math.sin(v) > 0 ? 1 * height : -1
    }
  }
}

// x轴文字竖向正文字显示
export function verticalXAXisLabel (value) {
  let ret = ''// 拼接加\n返回的类目项
  const maxLength = 1// 每项显示文字个数
  const valLength = value.length// X轴类目项的文字个数
  const rowN = Math.ceil(valLength / maxLength) // 类目项需要换行的行数
  if (rowN > 1) {
    for (let i = 0; i < rowN; i++) {
      let temp = ''// 每次截取的字符串
      const start = i * maxLength// 开始截取的位置
      const end = start + maxLength// 结束截取的位置
      temp = value.substring(start, end) + '\n'
      ret += temp // 凭借最终的字符串
    }
    return ret
  } else {
    return value
  }
}
